//poj 3177
/*该算法是R.Tarjan发明的。对图深度优先搜索，定义DFS(u)为u在搜索树（以下简称为树）中被遍历到的次序号。定义Low(u)为u或u的子树中能通过非父子边追溯到的最早的节点，即DFS序号最小的节点。根据定义，则有：

Low(u)=Min
{
DFS(u)
DFS(v) (u,v)为后向边(返祖边) 等价于 DFS(v)<DFS(u)且v不为u的父亲节点
Low(v) (u,v)为树枝边(父子边)
}

一个顶点u是割点，当且仅当满足(1)或(2)
(1) u为树根，且u有多于一个子树。
(2) u不为树根，且满足存在(u,v)为树枝边(或称父子边，即u为v在搜索树中的父亲)，使得DFS(u)<=Low(v)。

一条无向边(u,v)是桥，当且仅当(u,v)为树枝边，且满足DFS(u)<Low(v)。*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std ;
#define maxn  2001000
int n,m;
int M;
int first[5101],next[maxn]  ,E[maxn];
int flag[maxn];
void seee(int a[maxn],int n)
{
	int i;
	for(i=0; i<=n; i++)
		cout<<a[i]<<" ";
		cout<<endl;
}
void insert(int x,int y )
{
	next[M]=first[x];
	first[x]=M;
	 
	E[M]=y;
	M++;
}
void init()
{
	M=0;
	memset(first,-1,sizeof(first));
}

/**************求桥*****并且缩点到只剩桥边************************/
int root;
int Dfn[maxn],Low[maxn],Belong[maxn],Bcnt,Dindex;
//Belong里面存的就是缩点后每个点指向的缩点后的点
void  dfs(int u,int father)//深搜找时间戳
{
	int v,i,e,x;
	Dfn[u]=Low[u]=++Dindex;
	for(e=first[u]; e!=-1; e=next[e])
	{
		v=E[e];
		if(flag[e]) 
		{
			continue;
		}
		
		flag[e]=flag[e^1]=1;//只是为了重边问题解决
		//这一步只要不要让无向图访问到以前的访问过的边
		//有重边可以用边来判没有重边可以用点来判
		if(!Dfn[v])
		{
			dfs(v,u);
			Low[u]=min(Low[u],Low[v]);
		}
		else
		{
				Low[u]=min(Low[u],Dfn[v]);
		}
	}
}
void search(int u)
{
	int e,v;
	for(e=first[u];e!=-1; e=next[e])
	{
		v=E[e];
		
		if(!Belong[v])
		{
			if(Low[v]>Dfn[u])
				Belong[v]=++Bcnt;//桥的连通图缩点后只保留桥边，点从1到Bcnt;
			else
				Belong[v]=Belong[u];
			search(v);
		}		
	}
}
void bridge()
{
	int i;
	Dindex=0;//时间
	Bcnt=1;//桥的连通图缩点后只保留桥边，点从1到Bcnt;
	root=1; //默认这个连通图变成树是以1为根节点
	memset(Dfn,0,sizeof(Dfn));
	memset(Belong,0,sizeof(Belong));
	memset(flag,0,sizeof(flag));
	Belong[root]=1;
	
	
	dfs(root,-1);
	
	search(root);
}
/**************求桥*****并且缩点到只剩桥边************************/
int deg[5101];
int main()
{
	// freopen("in","r",stdin);
	int i,j;
	while(scanf("%d%d", &n,&m)!=EOF)
	{
		init();
		int a,b;
		for(i=1; i<=m; i++)
		{
			scanf("%d%d",&a,&b);
			insert(a,b);
			insert(b,a);
		}
		bridge();
		
 
		
		int e,u;
		memset(deg,0,sizeof(deg));
		for(i=1; i<=n; i++)
		{
			for(e=first[i]; e!=-1; e=next[e])
			{
				u=E[e];
				if(Belong[i]!=Belong[u])
				{
					deg[Belong[i]]++;
				}
			}
		}
		int res=0;
		for(i=1; i<=Bcnt; i++)
		{
			if(deg[i]==1)
				res++;
		}
		cout<<(res+1)/2<<endl;
	}	
}aa
